<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="snake.css">
</head>

<body>

</body>

</html>
<script>
    // 地图的构造函数
    function SnakeMap() {

    }
    // 地图构造函数中添加显示方法
    SnakeMap.prototype.show = function () {
        let divDom = document.createElement('div');
        divDom.className = 'map';
        // div加入到body标签中
        document.body.appendChild(divDom);
    }
    // 食物的构造函数
    function Food() {
        // 记录食物的坐标
        this.x = 0;
        this.y = 0;
        // 保存食物的div的dom对象
        this.foodDom = null;
    }
    Food.prototype.show = function () {
        if (!this.foodDom) {
            // 食物不存在 先创建标签在加入到页面上
            this.foodDom = document.createElement('div')
            this.foodDom.className = 'food';
            this.foodDom.style.position = 'absolute';
            // 现在这里是直接找页面上元素 如果存在2个map的样式怎么办
            document.querySelector('.map').appendChild(this.foodDom)
        }
        // 在生成随机数时 写的是固定的39 29数字 跟地图没关系
        this.x = this.makeRandom(0, 54);
        this.y = this.makeRandom(0, 44);
        this.foodDom.style.left = this.x * 20 + 'px';
        this.foodDom.style.top = this.y * 20 + 'px';
    }
    Food.prototype.makeRandom = function (min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

    // 蛇的构造函数
    function Snake() {
        // 记录蛇的移动方向
        this.direct = 'right';
        // 记录蛇的每一节的身体信息.由于每一节信息都需要记录，所以格式整体上为数组，由于每一节信息都存在多个信息需要记录。所以数组中每一个元素为对象.此时将数组中第一个元素作为蛇头部
        this.bodys = [
            // 每一个元素 dom属性记录 蛇每一节对应的div的dom对象，如果是null 表示目前的div还没有在页面上创建出来，否则就是dom对象
            { x: 2, y: 1, backgroundImage: "url('imgs/head.png')", dom: null },
            { x: 1, y: 1, backgroundImage: "url('imgs/body.png')", dom: null },
            { x: 0, y: 1, backgroundImage: "url('imgs/body.png')", dom: null }
        ];
    }
    // 蛇的原型上添加显示蛇的方法
    Snake.prototype.show = function () {
        // 创建三个div 设置到页面中
        for (let i = 0; i < this.bodys.length; i++) {
            if (!this.bodys[i].dom) {
                // 目前div的dom对象还不存在
                this.bodys[i].dom = document.createElement('div');
                this.bodys[i].dom.className = 'snake';
                // 设置蛇的每一节的背景图片 最后一个作为蛇头部
                this.bodys[i].dom.style.backgroundImage = this.bodys[i].backgroundImage;
                // 加入页面上
                document.querySelector('.map').appendChild(this.bodys[i].dom)
            }
            // 设置left值
            this.bodys[i].dom.style.left = this.bodys[i].x * 20 + 'px';
            this.bodys[i].dom.style.top = this.bodys[i].y * 20 + 'px';
        }
    }

    // 添加移动方法
    Snake.prototype.move = function () {
        // 移动就是修改蛇的每一节的坐标
        // 反向循环 修改坐标
        for (let i = this.bodys.length - 1; i > 0; i--) {
            this.bodys[i].x = this.bodys[i - 1].x;
            this.bodys[i].y = this.bodys[i - 1].y;
        }
        // 修改头部的坐标
        switch (this.direct) {
            case 'left':
                this.bodys[0].x -= 1;
                break;
            case 'right':
                this.bodys[0].x += 1;
                break;
            case 'up':
                this.bodys[0].y -= 1;
                break;
            case 'down':
                this.bodys[0].y += 1;
                break;
            default:
                break;
        }
        // 判断蛇是否吃到食物
        this.hasEat();
        if (!this.hasDie()) {
            this.show();
        }

    }
    // 判断蛇是否死亡
    Snake.prototype.hasDie = function () {
        let header = this.bodys[0];
        if (header.x < 0 || header.x > 54 || header.y < 0 || header.y > 44) {
            clearInterval(timer);
            alert('game over');
            return true;
        }
        return false;
    }
    // 
    Snake.prototype.hasEat = function () {
        // 使用蛇头部坐标与食物进行比较
        if (this.bodys[0].x == food.x && this.bodys[0].y == food.y) {
            // 吃到了食物 
            // 获取到蛇尾巴的序号
            let lastIndex = this.bodys.length - 1;
            // 将增加的一节设置到与尾巴重合
            this.bodys.push({
                x: this.bodys[lastIndex].x,
                y: this.bodys[lastIndex].y,
                backgroundImage: this.bodys[lastIndex].backgroundImage,
                dom: null
            });
            // 将食物再次随机
            food.show();
        }
    }

    let map = new SnakeMap;
    map.show();
    let food = new Food;
    food.show();
    let snake = new Snake;
    snake.show();
    // 设置定时器实现蛇的移动
    let timer = setInterval(function () {
        snake.move();
    }, 40);
    // 控制蛇的移动方向
    document.onkeydown = function (event) {
        switch (event.keyCode) {
            case 37:
                snake.direct = 'left';
                break;
            case 38:
                snake.direct = 'up';
                break;
            case 39:
                snake.direct = 'right';
                break;
            case 40:
                snake.direct = 'down';
                break;
            default:
                break;
        }
    }
</script>